package com.zone.gateway.assist.listener;

import com.zone.gateway.assist.config.ApiGatewayProperties;
import com.zone.gateway.assist.domain.model.aggregate.ApplicationGatewayRichInfo;
import com.zone.gateway.assist.domain.model.vo.ApplicationInterfaceMethodVO;
import com.zone.gateway.assist.domain.model.vo.ApplicationInterfaceVO;
import com.zone.gateway.assist.domain.model.vo.ApplicationSystemVO;
import com.zone.gateway.assist.domain.service.GatewayCenterService;
import com.zone.gateway.core.mapping.HttpCommonType;
import com.zone.gateway.core.mapping.HttpStatement;
import com.zone.gateway.core.session.Configuration;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;

/**
 * @author: zongzi
 * @description: TODO
 * @date: 2025/4/24
 */
public class GatewayListener implements ApplicationContextAware, ApplicationListener<ContextClosedEvent> {
    private final Logger logger = LoggerFactory.getLogger(GatewayListener.class);

    private final ApiGatewayProperties properties;
    private final GatewayCenterService registerService;
    private final Configuration configuration;
    private final Channel gatewaySocketChannel;

    public GatewayListener(ApiGatewayProperties properties, GatewayCenterService registerService, Configuration configuration, Channel gatewaySocketChannel) {
        this.properties = properties;
        this.registerService = registerService;
        this.configuration = configuration;
        this.gatewaySocketChannel = gatewaySocketChannel;
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        try {
            // 注册网关
            registerService.register(properties);
            // 注册映射关系
            this.addMapper(properties.getGatewayId());
        } catch (Exception e) {
            logger.error("网关启动失败", e);
            throw e;
        }
    }

    public void addMapper(String gatewayId) {
        // 拉取网关-应用配置列表
        ApplicationGatewayRichInfo applicationGatewayRichInfo = registerService.queryApplicationRichInfo(gatewayId, properties.getRegisterUrl());
        // 注册映射关系到通信组件
        for (ApplicationSystemVO applicationSystem : applicationGatewayRichInfo.getApplicationSystemList()) {
            for (ApplicationInterfaceVO interfaceVO : applicationSystem.getInterfaceList()) {
                // 注册配置
                configuration.regisConfig(applicationSystem.getSystemId(), applicationSystem.getSystemRegistry(), interfaceVO.getInterfaceId(), interfaceVO.getInterfaceVersion());
                // 注册rpc接口方法
                for (ApplicationInterfaceMethodVO method : interfaceVO.getMethodList()) {
                    HttpStatement httpStatement = new HttpStatement.Build()
                            .uri(method.getUri())
                            .applicationName(applicationSystem.getSystemId())
                            .interfaceName(interfaceVO.getInterfaceId())
                            .methodName(method.getMethodId())
                            .paramsType(method.getParameterType())
                            .type(HttpCommonType.valueOf(method.getHttpCommandType()))
                            .auth(method.getAuth())
                            .build();
                    configuration.addMapped(httpStatement);
                }
            }
        }
    }

    @Override
    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
        // 应用关闭，关闭netty server
        try {
            if (gatewaySocketChannel.isActive()) {
                gatewaySocketChannel.close();
            }
        } catch (Exception e) {
            logger.error("close netty server channel error", e);
        }
    }
}
